package com.mico.xchange.okcoin.service;

import com.mico.xchange.Exchange;
import com.mico.xchange.currency.CurrencyPair;
import com.mico.xchange.okcoin.FuturesContract;
import com.mico.xchange.okcoin.OkCoinAdapters;
import com.mico.xchange.okcoin.dto.trade.*;

import java.io.IOException;
import java.util.Set;
import java.util.stream.Collectors;

public class OkCoinTradeServiceRaw extends OKCoinBaseTradeService {

  protected static final String BATCH_DELIMITER = ",";

  /**
   * Constructor
   *
   * @param exchange
   */
  protected OkCoinTradeServiceRaw(Exchange exchange) {

    super(exchange);
  }

  public OkCoinTradeResult trade(String symbol, String type, String rate, String amount)
      throws IOException {

    OkCoinTradeResult tradeResult =
        okCoin.trade(apikey, symbol, type, rate, amount, signatureCreator());
    return returnOrThrow(tradeResult);
  }

  public OkCoinTradeResult cancelOrder(long orderId, String symbol) throws IOException {

    OkCoinTradeResult tradeResult = okCoin.cancelOrder(apikey, orderId, symbol, signatureCreator());
    return returnOrThrow(tradeResult);
  }

  public OkCoinBatchTradeResult cancelUpToThreeOrders(Set<Long> orderIds, String symbol)
      throws IOException {

    String ids =
        orderIds.stream().map(Object::toString).collect(Collectors.joining(BATCH_DELIMITER));
    return okCoin.cancelOrders(apikey, ids, symbol, signatureCreator());
  }

  public OkCoinOrderResult getOrder(long orderId, String symbol) throws IOException {

    OkCoinOrderResult orderResult = okCoin.getOrder(apikey, orderId, symbol, signatureCreator());
    return returnOrThrow(orderResult);
  }

  public OkCoinOrderResult getOrderHistory(
      String symbol, String status, String currentPage, String pageLength) throws IOException {

    OkCoinOrderResult orderResult =
        okCoin.getOrderHistory(apikey, symbol, status, currentPage, pageLength, signatureCreator());
    return returnOrThrow(orderResult);
  }

  /** OkCoin.com Futures API */
  public OkCoinTradeResult futuresTrade(
      String symbol,
      String type,
      String price,
      String amount,
      FuturesContract contract,
      int matchPrice,
      int leverRate)
      throws IOException {

    OkCoinTradeResult tradeResult =
        okCoin.futuresTrade(
            apikey,
            symbol,
            contract.getName(),
            type,
            price,
            amount,
            matchPrice,
            leverRate,
            signatureCreator());
    return returnOrThrow(tradeResult);
  }

  public OkCoinTradeResult futuresCancelOrder(long orderId, String symbol, FuturesContract contract)
      throws IOException {

    OkCoinTradeResult tradeResult =
        okCoin.futuresCancelOrder(apikey, orderId, symbol, contract.getName(), signatureCreator());
    return returnOrThrow(tradeResult);
  }

  public OkCoinFuturesOrderResult getFuturesOrder(
      long orderId, String symbol, String currentPage, String pageLength, FuturesContract contract)
      throws IOException {

    OkCoinFuturesOrderResult futuresOrder =
        okCoin.getFuturesOrder(
            apikey,
            orderId,
            symbol,
            "1",
            currentPage,
            pageLength,
            contract.getName(),
            signatureCreator());
    return returnOrThrow(futuresOrder);
  }

  public OkCoinPriceLimit getFuturesPriceLimits(CurrencyPair currencyPair, FuturesContract prompt)
      throws IOException {

    return okCoin.getFuturesPriceLimits(OkCoinAdapters.adaptSymbol(currencyPair), prompt.getName());
  }

  public OkCoinFuturesOrderResult getFuturesFilledOrder(
      long orderId, String symbol, String currentPage, String pageLength, FuturesContract contract)
      throws IOException {

    OkCoinFuturesOrderResult futuresOrder =
        okCoin.getFuturesOrder(
            apikey,
            orderId,
            symbol,
            "2",
            currentPage,
            pageLength,
            contract.getName(),
            signatureCreator());
    return returnOrThrow(futuresOrder);
  }

  public OkCoinFuturesOrderResult getFuturesOrders(
      String orderIds, String symbol, FuturesContract contract) throws IOException {

    OkCoinFuturesOrderResult futuresOrder =
        okCoin.getFuturesOrders(apikey, orderIds, symbol, contract.getName(), signatureCreator());
    return returnOrThrow(futuresOrder);
  }

  public OkCoinFuturesTradeHistoryResult[] getFuturesTradesHistory(
      String symbol, long since, String date) throws IOException {

    OkCoinFuturesTradeHistoryResult[] futuresHistory =
        okCoin.getFuturesTradeHistory(apikey, since, symbol, date, signatureCreator());
    return (futuresHistory);
  }

  public OkCoinPositionResult getFuturesPosition(String symbol, FuturesContract contract)
      throws IOException {
    OkCoinPositionResult futuresPositionsCross =
        okCoin.getFuturesPositionsCross(apikey, symbol, contract.getName(), signatureCreator());

    return returnOrThrow(futuresPositionsCross);
  }
}
